﻿using System;
using System.Collections.Generic;
using Moq;
using NUnit.Framework;
using Typed.Configuration.ConfigSource;
using Typed.Configuration.Implementation;

namespace Typed.Configuration.Tests
{
    [TestFixture]
    public class ConfigInterfaceImplBaseTests
    {
        Mock<UnifiedCovnerter> converterMock = new Mock<UnifiedCovnerter>();
        Mock<IStringConfigSource> sourceMock = new Mock<IStringConfigSource>();

        private class TestImpl : ConfigInterfaceImplBase
        {
            public void Init(IStringConfigSource src, UnifiedCovnerter converter)
            {
                var dict = new Dictionary<Type, UnifiedCovnerter>();
                dict.Add(converter.Type ?? typeof(string), converter);
                Init(new []{src}, dict);
            }

            public new T GetValue<T>(string fieldName)
            {
                return base.GetValue<T>(fieldName);
            }
        }

        [Test]
        public void AbsentValueThrowsException()
        {
            string ignore;
            sourceMock.Setup(q => q.TryGetString("foo", out ignore)).Returns(false);

            var target = GetTarget();
            Assert.Throws<InvalidOperationException>(() => target.GetValue<string>("foo"));
        }
        
        [Test]
        public void NullValueConvertedToDefault()
        {
            string value = null;
            sourceMock.Setup(q => q.TryGetString("foo", out value)).Returns(true);
            converterMock.Setup(q => q.GetDefaultValue()).Returns("Default");
            var target = GetTarget();
            Assert.AreEqual("Default", target.GetValue<string>("foo"));
        }

        private TestImpl GetTarget()
        {
            var target = new TestImpl();
            target.Init(sourceMock.Object, converterMock.Object);
            return target;
        }
    }
}